package cn.com.lms.business.exam.service;

import cn.com.lms.business.core.constant.ErrorEnum;
import cn.com.lms.business.exam.enums.PaperTypeEnum;
import cn.com.lms.business.exam.enums.QuickScoreTypeEnum;
import cn.com.lms.business.exam.persistence.entity.*;
import cn.com.lms.business.exam.persistence.repository.PaperRepository;
import cn.com.lms.business.exam.web.vo.PaperListVO;
import com.bnzj.core.exception.BusinessException;
import com.bnzj.core.persistence.BaseService;


import com.bnzj.core.persistence.query.QueryHelpBean;

import com.bnzj.core.util.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

@Service
public class PaperService extends BaseService<PaperRepository, Paper, Long> {

    @Autowired
    PaperSubjectService paperSubjectService;

    @Autowired
    PaperQuestionService paperQuestionService;

    @Autowired
    PaperQuickScoreService paperQuickScoreService;

    @Autowired
    PaperExtraService paperExtraService;

    public static QueryHelpBean getQueryHelpBean() {
        String selectSQL = "select *";
        String whereSQL = " from bnz_exam_paper where 1=1 ";
        QueryHelpBean queryBean = new QueryHelpBean(selectSQL + whereSQL, "select count(1)" + whereSQL, Paper.class);
        return queryBean;
    }

    public static QueryHelpBean getPaperListVOQueryHelpBean() {
        String selectSQL = "select p.id,p.paper_name,p.type, (case p.type when 1 then '固定' else '随机' end) type_name ,p.is_enable,p.is_delete,p.create_time,p.creator_name,e.paper_score,e.subject_count," +
                " (select count(1) from bnz_learning_stage_detail sd where sd.study_type=2 and sd.obj_id=p.id) as testCount ";
        String whereSQL = " from bnz_exam_paper p left join bnz_exam_paper_extra e on p.id=e.paper_id where 1=1 ";
        QueryHelpBean queryBean = new QueryHelpBean(selectSQL + whereSQL, "select count(1)" + whereSQL, PaperListVO.class);
        return queryBean;
    }

    @Override
    public Optional<Paper> findById(Long id) {
        Optional<Paper> paperOpt = super.findById(id);
        if (!paperOpt.isPresent()) {
            throw new BusinessException(ErrorEnum.RECORD_NOT_EXIST.getMessage(), "" + ErrorEnum.RECORD_NOT_EXIST.getCode());
        }
        if (PaperTypeEnum.FIXED_SELECTION.getValue().equals(paperOpt.get().getType())) {
            //根据试题ID,查询试题列表
            PaperSubject paperSubject = new PaperSubject();
            paperSubject.setPaperId(id);
            paperSubject.setIsDelete(false);
            List<PaperSubject> questionSubjectOptionList = paperSubjectService.findAll(paperSubject);
            paperOpt.get().setPaperSubjectList(questionSubjectOptionList);
        }
        if (PaperTypeEnum.RANDOM_QUESTION.getValue().equals(paperOpt.get().getType())) {
            //根据试题ID,查询试题列表
            PaperQuestion paperQuestion = new PaperQuestion();
            paperQuestion.setPaperId(id);
            paperQuestion.setIsDelete(false);
            List<PaperQuestion> paperQuestionList = paperQuestionService.findAll(paperQuestion);
            paperOpt.get().setPaperQuestionList(paperQuestionList);
        }

        return paperOpt;
    }


    @Transactional(rollbackFor = Exception.class)
    public Paper addPaper(Paper paper) {
        // 保存试卷信息
        Paper result = save(paper);
        Integer paperScore = 0; // 试卷总分
        Integer subjectCount = 0; // 试卷题目数


        List<Integer> scoreList = new CopyOnWriteArrayList<>();
        //指定题库随机出题
        List<Integer> subjectCountList = new CopyOnWriteArrayList<>();

        if (PaperTypeEnum.FIXED_SELECTION.getValue().equals(paper.getType())) {
            // 选择式固定出题
            List<PaperSubject> paperSubjectList = paper.getPaperSubjectList();
            if (!CollectionUtils.isEmpty(paperSubjectList)) {
                // 试卷题目数
                subjectCountList.add(paperSubjectList.size());
                List<PaperSubject> paperSubjects = paperSubjectList.stream().map(item -> {
                    PaperSubject paperSubject = new PaperSubject();
                    paperSubject.setIsDelete(item.getIsDelete() == null ? false : item.getIsDelete());
                    paperSubject.setScore(item.getScore());
                    paperSubject.setSortId(item.getSortId()==null?paperSubjectList.indexOf(item)+1:item.getSortId());
                    paperSubject.setSubjectId(item.getSubjectId());
                    paperSubject.setPaperId(result.getId());
                    paperSubject.setCreator(result.getCreator());
                    paperSubject.setCreateTime(result.getCreateTime());
                    paperSubject.setCreatorName(result.getCreatorName());
                    scoreList.add(item.getScore());

                    return paperSubject;
                }).collect(Collectors.toList());
                paperSubjectService.saveAll(paperSubjects);
            }
        } else if (PaperTypeEnum.RANDOM_QUESTION.getValue().equals(paper.getType())) {

            List<PaperQuestion> paperQuestionList = paper.getPaperQuestionList();
            if (!CollectionUtils.isEmpty(paperQuestionList)) {
                List<PaperQuestion> paperQuestions = paperQuestionList.stream().map(item -> {
                    PaperQuestion paperQuestion = new PaperQuestion();
                    paperQuestion.setIsDelete(item.getIsDelete() == null ? false : item.getIsDelete());
                    paperQuestion.setExplainCount(getValue(item.getExplainCount()));
                    paperQuestion.setFillCount(getValue(item.getFillCount()));
                    paperQuestion.setJudgeCount(getValue(item.getJudgeCount()));
                    paperQuestion.setMultipleCount(getValue(item.getMultipleCount()));
                    paperQuestion.setQuestionId(item.getQuestionId());
                    paperQuestion.setSingleCount(getValue(item.getSingleCount()));
                    paperQuestion.setPaperId(result.getId());
                    paperQuestion.setCreator(result.getCreator());
                    paperQuestion.setCreateTime(result.getCreateTime());
                    paperQuestion.setCreatorName(result.getCreatorName());
                    Integer paperQuestionTotalScore = this.sumPaperScore(result, paperQuestion);
                    Integer subjectTotalCount = this.sumSubjectCount(paperQuestion);
                    scoreList.add(paperQuestionTotalScore);
                    subjectCountList.add(subjectTotalCount);
                    return paperQuestion;
                }).collect(Collectors.toList());
                paperQuestionService.saveAll(paperQuestions);
            }


        } else {
            throw new BusinessException(ErrorEnum.PARAMETER_CANNOT_BE_EMPTY.getMessage(), "" + ErrorEnum.PARAMETER_CANNOT_BE_EMPTY.getCode());
        }
        // 试卷总分
        if (!CollectionUtils.isEmpty(scoreList)) {
            paperScore = scoreList.stream().collect(Collectors.summingInt(Integer::intValue));
        }
        // 随机试卷题目数
        if (!CollectionUtils.isEmpty(subjectCountList)) {
            subjectCount = subjectCountList.stream().collect(Collectors.summingInt(Integer::intValue));
        }
        // 保存试卷总分和题目数
        paperExtraService.savePaperExtra(result.getId(), paperScore, subjectCount);


        return result;
    }

    /**
     * 计算随机试卷题库分数
     *
     * @return
     */
    public Integer sumPaperScore(Paper paper, PaperQuestion paperQuestion) {
        Integer singleTotalScore = this.getValue(paper.getSingleScore()) * this.getValue(paperQuestion.getSingleCount());
        Integer multipleTotalScore = this.getValue(paper.getMultipleScore()) * this.getValue(paperQuestion.getMultipleCount());
        Integer judgeTotalScore = this.getValue(paper.getJudgeScore()) * this.getValue(paperQuestion.getJudgeCount());
        Integer fillTotalScore = this.getValue(paper.getFillScore()) * this.getValue(paperQuestion.getFillCount());
        Integer explainTotalScore = this.getValue(paper.getExplainScore()) * this.getValue(paperQuestion.getExplainCount());
        return (singleTotalScore + multipleTotalScore + judgeTotalScore + fillTotalScore + explainTotalScore);
    }

    /**
     * 计算随机试卷题库题数
     *
     * @return
     */
    public Integer sumSubjectCount(PaperQuestion paperQuestion) {
        Integer sCount = (this.getValue(paperQuestion.getSingleCount()));
        Integer mCount = (this.getValue(paperQuestion.getMultipleCount()));
        Integer jCount = (this.getValue(paperQuestion.getJudgeCount()));
        Integer fCount = (this.getValue(paperQuestion.getFillCount()));
        Integer eCount = (this.getValue(paperQuestion.getExplainCount()));
        return (sCount + fCount + mCount + jCount + eCount);
    }

    private Integer getValue(Integer value) {
        if (value == null) {
            return 0;
        }
        return value;
    }

    @Transactional(rollbackFor = Exception.class)
    public Paper updatePaper(Paper paper,Paper target) {
        BeanUtils.copyProperties(paper, target);
        save(target);
        Integer paperScore = 0;
        Integer subjectCount = 0;
        if (PaperTypeEnum.FIXED_SELECTION.getValue().equals(paper.getType())) {
            // 选择式固定出题
            List<PaperSubject> paperSubjects = paper.getPaperSubjectList();
            if (!CollectionUtils.isEmpty(paperSubjects)) {
                subjectCount = paperSubjects.size();
                paperScore = paperSubjects.stream().collect(Collectors.summingInt(PaperSubject::getScore));
            }

            int c=  paperSubjectService.deleteByPaperId(target.getId());
            if(c>=0) {
                paperSubjectService.batchSave(target, paperSubjects);
            }

        } else if (PaperTypeEnum.RANDOM_QUESTION.getValue().equals(paper.getType())) {
            //指定题库随机出题
            List<PaperQuestion> paperQuestions = paper.getPaperQuestionList();
            if (!CollectionUtils.isEmpty(paperQuestions)) {
                List<Integer> subjectCountList = new CopyOnWriteArrayList<>();
                List<Integer> scoreList = new CopyOnWriteArrayList<>();
                paperQuestions.forEach(item -> {
                    Integer paperQuestionTotalScore = this.sumPaperScore(target, item);
                    Integer subjectTotalCount = this.sumSubjectCount(item);
                    scoreList.add(paperQuestionTotalScore);
                    subjectCountList.add(subjectTotalCount);
                });
                // 随机试卷总分
                if (!CollectionUtils.isEmpty(scoreList)) {
                    paperScore = scoreList.stream().collect(Collectors.summingInt(Integer::intValue));
                }
                // 随机试卷试题总数
                if (!CollectionUtils.isEmpty(subjectCountList)) {
                    subjectCount = subjectCountList.stream().collect(Collectors.summingInt(Integer::intValue));
                }
            }
            paperQuestionService.deleteByPaperId(target.getId());
            paperQuestionService.batchSave(target, paperQuestions);


        } else {
            throw new BusinessException(ErrorEnum.PARAMETER_CANNOT_BE_EMPTY.getMessage(), "" + ErrorEnum.PARAMETER_CANNOT_BE_EMPTY.getCode());
        }

        // 保存试卷总分和题目数
        paperExtraService.savePaperExtra(target.getId(), paperScore, subjectCount);
        return target;
    }

    public int updateIsDelete(Boolean isDelete, List<Long> id) {
        return repository.updateIsDelete(isDelete, id);
    }

    public int updateIsEnable(Boolean isEnable, List<Long> id) {
        return repository.updateIsEnable(isEnable, id);
    }

    /**
     * 获取试卷总分
     *
     * @param paperIds
     * @return key-paperId value- paperScore
     */
    public List<Map> getPaperScoreByIdList(List<Long> paperIds) {

//
//        PaperQuickScore paperQuickScore=paperQuickScoreService.getQuickScore();
//        List<Paper> paperList=findAllById(paperIds);

        List<Map> mapList = new ArrayList<>();
        List<Map> paperScoreList = paperSubjectService.findPaperScoreByPaperIdList(paperIds);
        List<Map> paperScoreList2 = paperQuestionService.findPaperScoreByPaperIdList(paperIds);
        mapList.addAll(paperScoreList);
        mapList.addAll(paperScoreList2);



        return mapList;
    }
}
